#include "common/memory/memory_pool.h"
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <cstring>

namespace common {
namespace memory {

std::shared_ptr<MemoryPool> MemoryPool::create(size_t blockSize, size_t initialBlocks) {
    // 块大小至少为1字节
    if (blockSize < 1) {
        std::cerr << "内存块大小不能小于1字节" << std::endl;
        return nullptr;
    }
    
    // 创建内存池实例
    return std::shared_ptr<MemoryPool>(new MemoryPool(blockSize, initialBlocks));
}

MemoryPool::MemoryPool(size_t blockSize, size_t initialBlocks)
    : blockSize_(blockSize), initialBlocks_(initialBlocks),
      allocatedCount_(0), usedCount_(0), freeList_(nullptr) {
    // 初始化内存池
    grow(initialBlocks);
}

MemoryPool::~MemoryPool() {
    // 释放所有分配的内存块
    for (void* chunk : chunks_) {
        free(chunk);
    }
    chunks_.clear();
    freeList_ = nullptr;
}

void MemoryPool::grow(size_t blockCount) {
    if (blockCount == 0) {
        return;
    }
    
    // 分配一大块内存
    size_t chunkSize = blockSize_ * blockCount;
    void* newChunk = malloc(chunkSize);
    if (!newChunk) {
        std::cerr << "无法分配内存！" << std::endl;
        return;
    }
    
    // 记录分配的内存块
    chunks_.push_back(newChunk);
    
    // 将大块内存切分为小块，并加入空闲链表
    char* blockStart = static_cast<char*>(newChunk);
    for (size_t i = 0; i < blockCount; ++i) {
        void* blockPtr = blockStart + i * blockSize_;
        MemoryBlock* block = new MemoryBlock(blockPtr, blockSize_);
        
        // 链接到空闲列表
        block->next = freeList_;
        freeList_ = block;
        
        // 更新计数
        allocatedCount_++;
    }
}

void* MemoryPool::allocate() {
    std::lock_guard<std::mutex> lock(mutex_);
    
    // 查找空闲块
    MemoryBlock* block = findFreeBlock();
    if (!block) {
        // 没有空闲块，则增长内存池
        size_t growSize = allocatedCount_ / 2;  // 每次增长50%
        if (growSize < initialBlocks_) {
            growSize = initialBlocks_;
        }
        
        grow(growSize);
        block = findFreeBlock();
        
        if (!block) {
            std::cerr << "无法分配内存！" << std::endl;
            return nullptr;
        }
    }
    
    // 标记为已使用
    block->used = true;
    usedCount_++;
    
    return block->data;
}

void MemoryPool::deallocate(void* ptr) {
    if (!ptr) {
        return;
    }
    
    std::lock_guard<std::mutex> lock(mutex_);
    
    // 查找对应的内存块
    MemoryBlock* block = findBlock(ptr);
    if (!block) {
        std::cerr << "无法释放非内存池分配的内存！" << std::endl;
        return;
    }
    
    // 标记为未使用
    block->used = false;
    usedCount_--;
}

MemoryBlock* MemoryPool::findFreeBlock() {
    MemoryBlock* current = freeList_;
    while (current) {
        if (!current->used) {
            return current;
        }
        current = current->next;
    }
    return nullptr;
}

MemoryBlock* MemoryPool::findBlock(void* ptr) {
    MemoryBlock* current = freeList_;
    while (current) {
        if (current->data == ptr) {
            return current;
        }
        current = current->next;
    }
    return nullptr;
}

float MemoryPool::getUsageRatio() const {
    std::lock_guard<std::mutex> lock(mutex_);
    if (allocatedCount_ == 0) {
        return 0.0f;
    }
    return static_cast<float>(usedCount_) / allocatedCount_;
}

void MemoryPool::printStatus() const {
    std::lock_guard<std::mutex> lock(mutex_);
    std::cout << "内存池状态：" << std::endl;
    std::cout << "  块大小: " << blockSize_ << " 字节" << std::endl;
    std::cout << "  总块数: " << allocatedCount_ << std::endl;
    std::cout << "  使用块数: " << usedCount_ << std::endl;
    std::cout << "  使用率: " << (getUsageRatio() * 100) << "%" << std::endl;
    std::cout << "  内存分块数: " << chunks_.size() << std::endl;
}

} // namespace memory
} // namespace common 